package com.app.utils;

import com.app.pojo.FileInfo;
import com.app.pojo.MyFile;
import com.app.pojo.MyPath;
import com.app.config.Settings;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Transaction;

import java.io.File;
import java.util.ArrayList;
import java.util.Objects;

@Component//单例设计模式
public class FileManager1 {
    JedisPool jedisPool;

    String RFK_FLAG = ":";
    public FileManager1() {
        this.jedisPool = RedisUtils.getJedisPool();
    }

    public boolean creatFile(MyFile myFile, File recvFile){
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.set(myFile.getAbsolutePath(),myFile.getMd5());
            jedis.set(RFK_FLAG+myFile.getMd5(),myFile.getAbsolutePath());
            jedis.sadd(myFile.getMd5(), myFile.getAbsolutePath());
            return recvFile.renameTo(myFile.getRealFile(Settings.rootsDir));
        }
    }

    public ArrayList<FileInfo> getFileInfoList(MyPath path){
        ArrayList<FileInfo> list=new ArrayList<>();
        if (path==null||!path.isAvailable()) return list;
//        System.out.println("getFileInfoList :"+path);/***********打印***********/
        File dir = new File(Settings.rootsDir+"/"+path.getSourcePath());
        if (!dir.exists()) return list;
        try (Jedis jedis = jedisPool.getResource()) {
            for (File file : Objects.requireNonNull(dir.listFiles())){
                if (file.isFile()&&file.length()==0){//是空文件
                   String info = jedis.get(path.getSourcePath());
                   list.add(new FileInfo(file.getName(),info));
                }else list.add(new FileInfo(file));//是文件夹或本来文件
            }
        }catch (Exception e){e.printStackTrace();}
        return list;
    }
    public boolean delete(MyFile myFile){
//        if (myFile==null||myFile.getName()==null||!myFile.isAvailable()) return false;
        try (Jedis jedis = jedisPool.getResource()) {
            String delPath = myFile.getAbsolutePath();
            String md5= getMd5ByPath(delPath,jedis);
            String realPath = jedis.get(RFK_FLAG+md5);

            if (realPath==null) return false;
            if (delPath.equals(realPath)){
                //删除的是真实文件
                String newPath = jedis.spop(md5);
                if (newPath==null){
                    //删除后没有引用了，直接删除文件所有记录
                    if (myFile.getRealFile().delete()){
                        jedis.del(delPath,RFK_FLAG+md5);
                        return true;
                    }
                    return false;
                }
                //更新某个引用为真实文件
                if (myFile.getRealFile().renameTo(new File(Settings.rootsDir+"/"+newPath))){
                    jedis.set(RFK_FLAG+md5,newPath);
                    return true;
                }else {
                    //删除失败，写回去
                    jedis.sadd(md5,newPath);
                    return false;
                }
            }else {//删除的是引用
                if (myFile.getRealFile().delete()){
                    jedis.del(delPath);
                    jedis.srem(md5,delPath);
                    return true;
                }
            }
            return false;
        }catch (Exception e){e.printStackTrace();}
        return false;
    }
    public boolean copyToDir(MyFile source,MyPath targetDir){
        try (Jedis jedis = jedisPool.getResource()) {
            String md5 = getMd5ByPath(source.getAbsolutePath(),jedis);
            String targetPathname=targetDir.getSourcePath()+"/"+source.getName();
            if (new File(Settings.rootsDir+"/"+targetPathname).createNewFile()){
                jedis.set(targetPathname,jedis.get(source.getAbsolutePath()));
                jedis.sadd(md5,targetPathname);
                return true;
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


    //递归重命名后的子文件路径
    private void renameFlashPaths(String oldPath,String newPath,File dir,Jedis jedis){
        File[] childes=dir.listFiles();
        for (File child:childes){//更改目录下子文件
            String oldPathname=oldPath+"/"+child.getName();
            String newPathname=newPath+"/"+child.getName();
            if (child.isDirectory())
                renameFlashPaths(oldPathname,newPathname,child,jedis);
            else renameFileRedis(oldPathname,newPathname,jedis);
        }
    }
    private void renameFileRedis(String oldPathname,String newPathname,Jedis jedis){
        String md5 = getMd5ByPath(oldPathname,jedis);
        if (jedis.sismember(md5,oldPathname)){
            jedis.srem(md5,oldPathname);
            jedis.sadd(md5,newPathname);
        }else jedis.set(RFK_FLAG+md5,newPathname);
    }
    public boolean renameToMyFile(MyFile source,MyFile target){
        try (Jedis jedis = jedisPool.getResource()) {
            String oldPathname = source.getAbsolutePath();
            String newPathname = target.getAbsolutePath();
            File sourceFile=source.getRealFile();
            File targetFile=target.getRealFile();

            if (sourceFile.renameTo(target.getRealFile())){
                if (targetFile.isDirectory())//文件夹
                    renameFlashPaths(oldPathname,newPathname,targetFile,jedis);
                else //文件
                    renameFileRedis(oldPathname,newPathname,jedis);
                return true;
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }




    private File getRootFile(String path){
        return new File(Settings.rootsDir+"/"+path);
    }
    private String getMd5ByPath(String path,Jedis jedis){
        String info = jedis.get(path);
        if (info==null) return null;
        int pos = info.indexOf("|");
        if (pos>0) return info.substring(0,pos);
        return null;
    }
}
